#ifndef IRQ_H
#define IRQ_H

#include "comm/types.h"

#define IRQ0_DE   0     //除0异常
#define IRQ1_DB   1     //调试异常
#define IRQ2_NMI  2     //不可屏蔽的紧急中断
#define IRQ3_BP   3     //breakpoint
#define IRQ4_OF   4     //overflow
#define IRQ5_BR   5     //Bound Range Exceeded
#define IRQ6_UD   6     //无效的操作码
#define IRQ7_NM   7     //错误,设备不可用
#define IRQ8_DF   8     //double fault
#define IRQ10_TS  10    //invalid TSS
#define IRQ11_NP  11    //Segment not present
#define IRQ12_SS  12    //Stack-Segment Fault
#define IRQ13_GP  13    //General Protection
#define IRQ14_PF  14    //Page Fault
#define IRQ16_MF  16    //Math Fault
#define IRQ17_AC  17    //Alignment Check
#define IRQ18_MC  18    //Machine check
#define IRQ19_XM  19    //SIMD Floating-Point Exeption
#define IRQ20_VE  20    //Vitualization Exception
#define IRQ21_CP  21    //Control Protection Exception

#define IRQ0_TIMER          0x20
#define IRQ1_KEYBOARD       0x21

#define IRQ14_HARDDISK_PRIMARY  (0x20 + 14)

#define ERR_PAGE_P          (1<<0)
#define ERR_PAGE_W          (1<<1)
#define ERR_PAGE_US         (1<<1)

#define ERR_EXT             (1<<0)
#define ERR_IDT             (1<<1)


typedef struct  _exception_frame_t
{
    int gs,fs,es,ds;
    int edi,esi,ebp,esp,ebx,edx,ecx,eax;
    int num;
    int error_code;
    int eip,cs,eflags;
    uint32_t esp3,ss3;
}exception_frame_t;

typedef void (*irq_handler_t)(void);

void irq_init();

void exception_handler_unknown();
void exception_handler_divide();
void exception_handler_debug();
void exception_handler_NMI();
void exception_handler_breakpoint();
void exception_handler_overflow();
void exception_handler_bound_range();
void exception_handler_invalid_opcode();
void exception_handler_device_unavailable();
void exception_handler_double_fault();
void exception_handler_invalid_tss();
void exception_handler_segment_not_present();
void exception_handler_stack_segment_fault();
void exception_handler_general_protection();
void exception_handler_page_fault();
void exception_handler_fpu_error();
void exception_handler_alignment_check();
void exception_handler_machine_check();
void exception_handler_simd_exception();
void exception_handler_virtual_exception();
void exception_handler_control_exception();

void do_handler_divide (exception_frame_t * frame);

int irq_install(int irq_num,irq_handler_t handler);

// PIC控制器相关的寄存器及位配置
#define PIC0_ICW1			0x20
#define PIC0_ICW2			0x21
#define PIC0_ICW3			0x21
#define PIC0_ICW4			0x21
#define PIC0_OCW2			0x20
#define PIC0_IMR			0x21

#define PIC1_ICW1			0xa0
#define PIC1_ICW2			0xa1
#define PIC1_ICW3			0xa1
#define PIC1_ICW4			0xa1
#define PIC1_OCW2			0xa0
#define PIC1_IMR			0xa1

#define PIC_ICW1_ICW4		(1 << 0)		// 1 - 需要初始化ICW4
#define PIC_ICW1_ALWAYS_1	(1 << 4)		// 总为1的位
#define PIC_ICW4_8086	    (1 << 0)        // 8086工作模式

#define PIC_OCW2_EOI		(1 << 5)		// 1 - 非特殊结束中断EOI命令

#define IRQ_PIC_START		0x20			// PIC中断起始号

void irq_enable(int irq_num);
void irq_disable(int irq_num);
void irq_disable_global(void);
void irq_enable_global(void);

void pic_send_eoi(int irq_num);


typedef uint32_t irq_state_t;
irq_state_t irq_enter_protection();    //进入临界区
void irq_leave_protection(irq_state_t state);    //退出临界区

#endif
